package com.vanka.config;

import com.vanka.entity.account.Permission;
import com.vanka.mapper.account.PermissionMapper;
import com.vanka.service.LoginService;
import com.vanka.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import sun.plugin2.applet.context.NoopExecutionContext;
import sun.security.provider.PolicyParser;

import java.util.ArrayList;
import java.util.List;

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private LoginService loginService;
    @Autowired
    private PermissionMapper permissionMapper;
    /**
     * 动态配置授权账户
     * @param auth auth
     * @throws Exception e
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        super.configure(auth);
        /*auth.inMemoryAuthentication()
                .withUser("yxf")//账号
                .password("123456")//密码
                .authorities("add", "del", "show", "update");//角色权限*/
        auth.userDetailsService(loginService).passwordEncoder(new PasswordEncoder() {
            //生成密码
            @Override
            public String encode(CharSequence rawPassword) {
                return MD5Util.encode((String) rawPassword);
            }
            //比较密码
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                // md5 传递密码 传递密码 MD5 加密 ===DB中密码 密码输入正确的
                String rawPass = MD5Util.encode((String) rawPassword);
                boolean result = rawPass.equals(encodedPassword);
                return result;
            }
        });

    }

    /**
     * 新增 HttpSecurity配置
     * 拦截所有请求 认证
     * @param http http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置认证方式
//        http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();

        /*http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("add")
                .antMatchers("/delMember").hasAnyAuthority("del")
                .antMatchers("/updateMember").hasAnyAuthority("update")
                .antMatchers("/showMember").hasAnyAuthority("show")
                //允许不被拦截
                .antMatchers("/login").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin()
                //
                .loginPage("/login").and().csrf().disable();*/

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
                a = http.authorizeRequests();

        //查询需要查询到的所有权限
        List<Permission> all = permissionMapper.selectList(null);
        //遍历
        all.forEach((p -> {
            a.antMatchers(p.getUrl()).hasAnyAuthority(p.getTag());//添加规则
        }));

        a.antMatchers("/login").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin()
                .loginPage("/login").and().csrf().disable();
    }
    /**
     * There is no PasswordEncoder mapped for the id "null"
     * 原因:升级为Security5.0以上密码支持多中加密方式，恢复以前模式
     * @return
     */
    @Bean
    public NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}
